﻿using System;
using System.Collections.Generic;
using System.Data.Objects;
using System.Linq;
using System.Linq.Expressions;
using System.Text;
using SMS.MODEL;

namespace SMS.DAL
{
    public class SMSRepository<T> : ISMSRepository<T> where T : class
    {
       
       /// <summary>

    /// The context object for the database

    /// </summary>

    private ObjectContext _context;

 
    /// <summary>

    /// The IObjectSet that represents the current entity.

    /// </summary>

    private IObjectSet<T> _objectSet;

 

    /// <summary>

    /// Initializes a new instance of the DataRepository class

    /// </summary>

    public SMSRepository()

        : this(new SMSEntities())

    {

    }

 

    /// <summary>

    /// Initializes a new instance of the DataRepository class

    /// </summary>

    /// <param name="context">The Entity Framework ObjectContext</param>

    public SMSRepository(ObjectContext context)

    {

        _context = context;

        _objectSet = _context.CreateObjectSet<T>();

    }

 

    /// <summary>

    /// Gets all records as an IQueryable

    /// </summary>

    /// <returns>An IQueryable object containing the results of the query</returns>

    public IQueryable<T> Fetch()

    {

        return _objectSet;

    }

   
    /// <summary>

    /// Finds a record with the specified criteria

    /// </summary>

    /// <param name="predicate">Criteria to match on</param>

    /// <returns>A collection containing the results of the query</returns>

    public IEnumerable<T> Find(Func<T, bool> predicate)

    {
       
        return _objectSet.Where<T>(predicate);
    }

 

    /// <summary>

    /// Gets a single record by the specified criteria (usually the unique identifier)

    /// </summary>

    /// <param name="predicate">Criteria to match on</param>

    /// <returns>A single record that matches the specified criteria</returns>

    public T Single(Func<T, bool> predicate)

    {

        return _objectSet.Single<T>(predicate);

    }

 

    /// <summary>

    /// The first record matching the specified criteria

    /// </summary>

    /// <param name="predicate">Criteria to match on</param>

    /// <returns>A single record containing the first record matching the specified criteria</returns>

    public T First(Func<T, bool> predicate)

    {

        return _objectSet.First<T>(predicate);

    }

 

    /// <summary>

    /// Deletes the specified entitiy

    /// </summary>

    /// <param name="entity">Entity to delete</param>

    /// <exception cref="ArgumentNullException"> if <paramref name="entity"/> is null</exception>

    public void Delete(T entity)

    {

        if (entity == null)

        {

            throw new ArgumentNullException("entity");

        }

 

        _objectSet.DeleteObject(entity);

    }

 

    /// <summary>

    /// Deletes records matching the specified criteria

    /// </summary>

    /// <param name="predicate">Criteria to match on</param>

    public void Delete(Func<T, bool> predicate)

    {

        IEnumerable<T> records = from x in _objectSet.Where<T>(predicate) select x;

 

        foreach (T record in records)

        {

            _objectSet.DeleteObject(record);

        }

    }

 

    /// <summary>

    /// Adds the specified entity

    /// </summary>

    /// <param name="entity">Entity to add</param>

    /// <exception cref="ArgumentNullException"> if <paramref name="entity"/> is null</exception>

    public void Add(T entity)

    {

        if (entity == null)

        {

            throw new ArgumentNullException("entity");

        }

 

        _objectSet.AddObject(entity);

    }

 

    /// <summary>

    /// Attaches the specified entity

    /// </summary>

    /// <param name="entity">Entity to attach</param>

    public void Attach(T entity)

    {

        _objectSet.Attach(entity);

    }

 

    /// <summary>

    /// Saves all context changes

    /// </summary>

    public void SaveChanges()

    {

        _context.SaveChanges();

    }

 

    /// <summary>

    /// Saves all context changes with the specified SaveOptions

    /// </summary>

    /// <param name="options">Options for saving the context</param>

    public void SaveChanges(SaveOptions options)

    {

        _context.SaveChanges(options);

    }

 

    /// <summary>

    /// Releases all resources used by the WarrantManagement.DataExtract.Dal.ReportDataBase

    /// </summary>

    public void Dispose()

    {

        Dispose(true);

        GC.SuppressFinalize(this);

    }

 

    /// <summary>

    /// Releases all resources used by the WarrantManagement.DataExtract.Dal.ReportDataBase

    /// </summary>

    /// <param name="disposing">A boolean value indicating whether or not to dispose managed resources</param>

    protected virtual void Dispose(bool disposing)

    {

        if (disposing)

        {

            if (_context != null)

            {

                _context.Dispose();

                _context = null;

            }

        }

    }

    }

}
